package com.example.music.Test;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.example.music.utility.AESUtils;
import com.example.music.utility.MyUtil;

import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 网易云
 *
 * @author yzh
 * @date 2023/04/07
 */
public class NetEase {
    /*
     * 网易访问都需要两个参数：params，encSecKey;并且访问类型content-Type一定要设置为"application/x-www-form-urlencoded"
     * 这两个参数都是加密过的，但是通过分析发现有很多值是固定的,e,f,g是固定的; encSecKey是由i,e,f 加密得来的，其中i是随机通过AES加密得来的，这个值其实也可以看作固定值，直接用网易云自动生成的就可以,所以encSecKey也是固定的值
     * e:"010001"
     * f:"00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"
     * g:"0CoJUm6Qyw8W8jud"
     * params是由d,g进行AES加密得到字符串，再用这个字符串和i进行AES加密得来,d是搜索的一些参数，
     * 例如：d: "{\"hlpretag\":\"<span class=\\\"s-fc7\\\">\",\"hlposttag\":\"</span>\",\"s\":\"晴天\",\"type\":\"1\",\"offset\":\"0\",\"total\":\"true\",\"limit\":\"30\",\"csrf_token\":\"\"}"
     *
     *
     */
    //网易固定的IV
    private static String IV = "0102030405060708";
    //网易固定的Key
    private static String netease_g = "0CoJUm6Qyw8W8jud";
    //随机出来的Key
    private static String netease_i = "8KJ8l67XRLiDt2FZ";

    private static String encSecKey = "23962e3bc106171ca9daa70494c6b451343171a3ee983d885d7e694c4132bcee7057f5b0de18435969cd4296a9d31820075ce7730040a9a06939d6226327017fbcc4a8e723faf5f81f74acee1dfc91edde5c93652f010e28ca1a2a17ddbe863c3d09fd15e1d04833c479cad357eca5ff5687b00e4b3d288ed0a62c2e53d6b6d7";

    public static void main(String[] args) throws Exception {
        long l = System.currentTimeMillis();
        JSONArray list = Get_playlist_music_url("2312165875");

        String regEx = "[`~!@#$%^&*+=|{}':;',//[//].<>/?~！@#￥%……&*——+|{}【】‘；：”“’。，、？]";
        Pattern pattern = Pattern.compile(regEx);

        for (int i = 0; i < list.size(); i++) {
            String url = JSON.parseObject(list.getString(i)).getString("url");
            String name = JSON.parseObject(list.getString(i)).getString("name");
            Matcher matcher = pattern.matcher(name);
            String path = "D:\\test\\" + matcher.replaceAll("") + ".mp3";
            Thread thread = new Thread(new download(url, path));
            thread.start();
        }

        System.out.println(System.currentTimeMillis() - l);
    }

    public static String search(String keyword, String type) throws Exception {

        /*type默认为 1 即单曲 , 取值意义 : 1: 单曲, 10: 专辑, 100: 歌手, 1000: 歌单, 1002: 用户, 1004: MV, 1006: 歌词, 1009: 电台, 1014: 视频, 1018:综合, 2000:声音(搜索声音返回字段格式会不一样)*/
        String content = "{\"s\":\"" + keyword + "\",\"type\":\"" + type + "\",\"offset\":\"0\",\"total\":\"true\",\"limit\":\"50\",\"csrf_token\":\"\"}";

        String url = "https://music.163.com/weapi/cloudsearch/get/web?csrf_token=";

        String encrypt = AESUtils.encrypt(content, netease_g, IV);
        String encText = AESUtils.encrypt(encrypt, netease_i, IV);

        String s = HttpRequest.post(url)
                .timeout(20000)//超时，毫秒
                .contentType("application/x-www-form-urlencoded")
                .form("params", encText)
                .form("encSecKey", encSecKey)
                .execute().body();

        String playLists = JSON.parseObject(JSON.parseObject(s).getString("result")).getString("playlists");
        String songs = JSON.parseObject(JSON.parseObject(s).getString("result")).getString("songs");
        String result = type.equals("1000") ? playLists : songs;
        return result;
        /*JSONArray array = JSON.parseArray(result);

        ArrayList<String> list = new ArrayList<>();
        for (int i = 0; i < array.size(); i++) {
            System.out.println(array.get(i).toString());

        }

*/

    }

    /**
     * 获取音乐网址
     *
     * @param id id(可放入多个id,用逗号隔开,例如传入"1915312754,167655")
     * @throws Exception 异常
     * @author yzh
     * @time 2023/4/10
     */
    public static String GetMusicUrl(String id) throws Exception {
        String content = "{\"ids\":\"[" + id + "]\",\"level\":\"standard\",\"encodeType\":\"aac\",\"csrf_token\":\"\"}";

        String url = "https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token=";

        String encrypt = AESUtils.encrypt(content, netease_g, IV);
        String encText = AESUtils.encrypt(encrypt, netease_i, IV);

        String s = HttpRequest.post(url)
                .timeout(20000)//超时，毫秒
                .contentType("application/x-www-form-urlencoded")
                .form("params", encText)
                .form("encSecKey", encSecKey)
                .execute().body();
        return JSON.parseObject(s).getString("data");
    }
   /* "{\"id\":\"26467411\",\"offset\":0,\"total\":true,\"limit\":1000,\"n\":1000,\"csrf_token\":\"\"}"
            "{\"c\":\"[{\\\"id\\\":430685732},{\\\"id\\\":22707008},{\\\"id\\\":16846091},{\\\"id\\\":26127164},{\\\"id\\\":5308028},{\\\"id\\\":698479},{\\\"id\\\":493478198},{\\\"id\\\":36897723},{\\\"id\\\":5307982},{\\\"id\\\":27514120},{\\\"id\\\":16846088},{\\\"id\\\":22676167},{\\\"id\\\":5101648},{\\\"id\\\":578090},{\\\"id\\\":434902428},{\\\"id\\\":5254129},{\\\"id\\\":1638654},{\\\"id\\\":28283137},{\\\"id\\\":857896},{\\\"id\\\":451319227},{\\\"id\\\":31066449},{\\\"id\\\":22844535},{\\\"id\\\":26237342},{\\\"id\\\":116493},{\\\"id\\\":22822506},{\\\"id\\\":139718},{\\\"id\\\":4341314},{\\\"id\\\":5307932},{\\\"id\\\":28406526},{\\\"id\\\":1993749},{\\\"id\\\":22712173},{\\\"id\\\":5271071},{\\\"id\\\":27707270},{\\\"id\\\":1091873},{\\\"id\\\":22802176},{\\\"id\\\":139774},{\\\"id\\\":1091088},{\\\"id\\\":443521},{\\\"id\\\":103301},{\\\"id\\\":103035},{\\\"id\\\":5267808},{\\\"id\\\":22743825},{\\\"id\\\":21725725},{\\\"id\\\":406232}]\",\"ids\":\"[430685732,22707008,16846091,26127164,5308028,698479,493478198,36897723,5307982,27514120,16846088,22676167,5101648,578090,434902428,5254129,1638654,28283137,857896,451319227,31066449,22844535,26237342,116493,22822506,139718,4341314,5307932,28406526,1993749,22712173,5271071,27707270,1091873,22802176,139774,1091088,443521,103301,103035,5267808,22743825,21725725,406232]\"}"
*/

    /**
     * 获取歌单信息(包括歌单里所有的音乐id)
     *
     * @author yzh
     * @time 2023/4/10
     */
    public static String Get_playlist_music(String id) throws Exception {
        String content = "{\"id\":\"" + id + "\",\"n\":\"1000\",\"offset\":\"0\",\"total\":\"true\",\"limit\":\"1000\",\"csrf_token\":\"\"}";

        String url = "https://music.163.com/weapi/v3/playlist/detail";
        String encrypt = AESUtils.encrypt(content, netease_g, IV);
        String encText = AESUtils.encrypt(encrypt, netease_i, IV);

        String s = HttpRequest.post(url)
                .timeout(20000)//超时，毫秒
                .contentType("application/x-www-form-urlencoded")
                .form("params", encText)
                .form("encSecKey", encSecKey)
                .execute().body();

        String trackIds = JSON.parseObject(JSON.parseObject(s).getString("playlist")).getString("trackIds");
        return trackIds;
    }

    /**
     * 获取歌曲详细信息
     *
     * @param id id
     * @throws Exception 异常
     */
    public static String Get_music_detail(String id) throws Exception {
        String content = "{\"c\":\"[{\\\"id\\\":\\\"" + id + "\\\"}]\",\"csrf_token\":\"\"}";
        String url = "https://music.163.com/weapi/v3/song/detail";
        String encrypt = AESUtils.encrypt(content, netease_g, IV);
        String encText = AESUtils.encrypt(encrypt, netease_i, IV);

        String s = HttpRequest.post(url)
                .timeout(20000)//超时，毫秒
                .contentType("application/x-www-form-urlencoded")
                .form("params", encText)
                .form("encSecKey", encSecKey)
                .execute().body();
        String songs = JSON.parseObject(s).getString("songs");
        return songs;
    }

    /**
     * 获取音乐名字
     *
     * @param id id
     * @return {@link String}
     * @throws Exception 异常
     */
    public static String Get_musicName(String id) throws Exception {
        String s = Get_music_detail(id);
        String substring = s.substring(1, s.length() - 1);
        String name = JSON.parseObject(substring).getString("name");
        return name;
    }

    public static JSONArray Get_playlist_music_url(String playlistid) throws Exception {
        String s = Get_playlist_music(playlistid);
        JSONArray array = JSON.parseArray(s);
        String ids = "";
        for (int i = 0; i < array.size(); i++) {
            String id = JSON.parseObject(array.get(i).toString()).getString("id");
            ids += id + ",";
        }
        ids = ids.substring(0, ids.lastIndexOf(","));

        String urls = GetMusicUrl(ids);
        JSONArray jsonArray = JSON.parseArray(urls);
        JSONArray list = new JSONArray();
        JSONArray fail = new JSONArray();

        for (int i = 0; i < jsonArray.size(); i++) {
            HashMap<String, String> map = new HashMap<>();
            String url = JSON.parseObject(jsonArray.getString(i)).getString("url");
            String name = Get_musicName(JSON.parseObject(jsonArray.getString(i)).getString("id"));
            if (MyUtil.isEmpty(url)) {
                map.put("id", JSON.parseObject(jsonArray.getString(i)).getString("id"));
                map.put("name", name);
                fail.add(map);
            } else {
                map.put("name", name);
                map.put("url", url);
                list.add(map);
            }
        }
        if (fail.size() > 0) {
            System.out.println("这些没有链接:" + fail);
        }

        return list;
    }
}
